package com.example.chamberlainserver.mapper;

import com.example.chamberlainserver.Entry.UserLoginLog;
import com.example.chamberlainserver.dto.UserLoginLogQueryDTO;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 用户登录日志Mapper接口
 */
@Mapper
public interface UserLoginLogMapper {
    
    /**
     * 插入登录日志
     * @param loginLog 登录日志对象
     * @return 影响行数
     */
    @Insert("INSERT INTO user_login_log (user_id, username, login_ip, login_device, login_status, fail_reason, login_time, create_time) " +
            "VALUES (#{userId}, #{username}, #{loginIp}, #{loginDevice}, #{loginStatus}, #{failReason}, #{loginTime}, #{createTime})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(UserLoginLog loginLog);
    
    /**
     * 更新登出信息
     * @param id 日志ID
     * @param logoutTime 登出时间
     * @param sessionDuration 会话时长
     * @return 影响行数
     */
    @Update("UPDATE user_login_log SET logout_time = #{logoutTime}, session_duration = #{sessionDuration}, update_time = NOW() " +
            "WHERE id = #{id} AND logout_time IS NULL")
    int updateLogout(@Param("id") Long id, @Param("logoutTime") LocalDateTime logoutTime, @Param("sessionDuration") Long sessionDuration);
    
    /**
     * 更新登出信息（XML方式）
     * @param id 日志ID
     * @param logoutTime 登出时间
     * @return 影响行数
     */
    int updateLogoutInfo(@Param("id") Long id, @Param("logoutTime") LocalDateTime logoutTime);
    
    /**
     * 获取指定时间段内的登录日志
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 登录日志列表
     */
    @Select("SELECT * FROM user_login_log WHERE login_time BETWEEN #{startTime} AND #{endTime} ORDER BY login_time DESC")
    List<UserLoginLog> getLoginLogsByTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 获取指定用户的登录日志
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 登录日志列表
     */
    @Select("SELECT * FROM user_login_log WHERE user_id = #{userId} ORDER BY login_time DESC LIMIT #{limit}")
    List<UserLoginLog> getLoginLogsByUserId(@Param("userId") int userId, @Param("limit") int limit);
    
    /**
     * 获取指定时间段内的登录总数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 登录总数
     */
    @Select("SELECT COUNT(*) FROM user_login_log WHERE login_time BETWEEN #{startTime} AND #{endTime} AND login_status = true")
    int getLoginCountByTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 获取指定时间段内的独立用户数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 独立用户数
     */
    @Select("SELECT COUNT(DISTINCT user_id) FROM user_login_log WHERE login_time BETWEEN #{startTime} AND #{endTime} AND login_status = true")
    int getUniqueUserCountByTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 获取指定时间段内每天的登录次数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 日期和登录次数的列表
     */
    @Select("SELECT DATE_FORMAT(login_time, '%Y-%m-%d') as date, COUNT(*) as count " +
            "FROM user_login_log " +
            "WHERE login_time BETWEEN #{startTime} AND #{endTime} AND login_status = true " +
            "GROUP BY DATE_FORMAT(login_time, '%Y-%m-%d') " +
            "ORDER BY date")
    List<Map<String, Object>> getDailyLoginCounts(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
    
    /**
     * 根据用户名获取最近的登录日志ID
     * @param username 用户名
     * @return 登录日志ID
     */
    @Select("SELECT id FROM user_login_log WHERE username = #{username} AND login_status = true AND logout_time IS NULL ORDER BY login_time DESC LIMIT 1")
    Long getLatestLoginLogIdByUsername(@Param("username") String username);
    
    /**
     * 分页查询登录日志
     * @param queryDTO 查询条件
     * @return 登录日志列表
     */
    List<UserLoginLog> pageLoginLogs(UserLoginLogQueryDTO queryDTO);
    
    /**
     * 统计符合条件的登录日志总数
     * @param queryDTO 查询条件
     * @return 总数
     */
    int countLoginLogs(UserLoginLogQueryDTO queryDTO);
}